package com.hkzhao.reportingsystem.service.impl;

import cn.hutool.extra.template.engine.velocity.VelocityEngine;
import com.github.pagehelper.PageHelper;
import com.hkzhao.reportingsystem.common.api.CommonResult;
import com.hkzhao.reportingsystem.common.utils.JwtTokenUtil;
import com.hkzhao.reportingsystem.common.utils.TranslateToToken;
import com.hkzhao.reportingsystem.component.OverTimeCancelSender;
import com.hkzhao.reportingsystem.component.RegisterSender;
import com.hkzhao.reportingsystem.dao.ReportSystemDao;
import com.hkzhao.reportingsystem.dto.CaseDto;
import com.hkzhao.reportingsystem.mbg.mapper.CaseMapper;
import com.hkzhao.reportingsystem.mbg.mapper.DoctorMapper;
import com.hkzhao.reportingsystem.mbg.mapper.UserPermissionMapper;
import com.hkzhao.reportingsystem.mbg.model.Case;
import com.hkzhao.reportingsystem.mbg.model.Doctor;
import com.hkzhao.reportingsystem.mbg.model.DoctorExample;
import com.hkzhao.reportingsystem.service.DoctorService;
import com.hkzhao.reportingsystem.service.RedisStringService;
import com.hkzhao.reportingsystem.service.RedisTmpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

@Service
public class DoctorServiceImpl implements DoctorService {
    private static final Logger LOGGER = LoggerFactory.getLogger(DoctorServiceImpl.class);
    @Value("${redis.key.expire.authCode}")
    private Long second;
    @Value("${redis.key.prefix.authCode}")
    private String auth_header;
    @Value("${redis.key.doctorRegister.authCode}")
    private String doctor_prefix;
    @Value("${redis.key.casePrefix.authCode}")
    private String redis_auth_Case_key;
    @Autowired
    private RedisStringService redisService;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired(required = false)
    private VelocityEngine velocityEngine;
    @Autowired(required = false)
    private DoctorMapper doctorMapper;
    @Autowired(required = false)
    private UserPermissionMapper userPermissionMapper;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private OverTimeCancelSender overTimeCancelSender;
    @Autowired
    private RegisterSender registerSender;
    @Autowired(required = false)
    private CaseMapper caseMapper;
    @Autowired(required = false)
    private ReportSystemDao reportSystemDao;
    @Autowired(required = false)
    private RedisTmpService redisTmpService;
    @Override
    public CommonResult register(String username, String password, String worker_id, String doctor_type, String province,String identify_id,String validCode,String email) {
        if(getValidCode(email)==null)
            return CommonResult.failed("没有该邮箱的验证码");
        if(!getValidCode(email).equals(validCode))
            return CommonResult.failed("邮箱验证码错误");
        String  Doctor_token_id = TranslateToToken.GetGUID();
        if(redisService.get(doctor_prefix+username)!=null)
            return CommonResult.failed("该用户名也被占用,请重新输入");
        if(doctorMapper.selectByPrimaryKey(username)!=null)
            return CommonResult.failed("该用户名也被占用,请重新输入");
        Doctor doctor = new Doctor();
        doctor.setUsername(username);doctor.setWokerId(worker_id);
        doctor.setProvince(province);doctor.setIdentifyId(identify_id);
        doctor.setDoctorType(doctor_type);doctor.setDoctorTokenId(Doctor_token_id);doctor.setPassword(passwordEncoder.encode(password));
        doctor.setStatus(0);
        doctorMapper.insert(doctor);
        LOGGER.info("doctor register request username:{}",username);
        senDelayMessageCancelVerify(username);
        return CommonResult.success("成功注册用户，已提交申请,请等待12h审核");
    }

    public CommonResult sendDelayReigsterEmail(String username)
    {   String validCode = valid_register(username);
        long delayTimes = 30;
        registerSender.sendMessage(new String[]{username,validCode},delayTimes);
        return CommonResult.success(validCode,"用户验证码");
    }
    private void senDelayMessageCancelVerify(String username)
    {
        long delayTimes = 30*1000*12;
        overTimeCancelSender.sendMessage(username,delayTimes);
    }
    private String valid_register(String emailaddress) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        redisService.set(auth_header+emailaddress,sb.toString());
        redisService.expire(auth_header+emailaddress,240);
        return sb.toString();
    }
    public CommonResult send_email(String emailaddress,String message){
        /*SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("1223602915@qq.com");
        message.setTo(emailaddress);
        message.setSubject("主题：直报系统注册验证码");
        message.setText(sb);
        mailSender.send(message);*/
        return CommonResult.success(message,"成功发送该邮件");
    }
    private String getValidCode(String email){
      return   redisService.get(auth_header+email);
    }

    @Override
    public Doctor getDoctorByUsername(String username) {
        DoctorExample doctorExample = new DoctorExample();
        doctorExample.createCriteria().andUsernameEqualTo(username);
        List<Doctor> list = doctorMapper.selectByExample(doctorExample);
        if(list!=null&&list.size()>0)
            return list.get(0);
        return null;
    }



    @Override
    public String login(String username, String password) {
        String token = null;
        try{
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if(!passwordEncoder.matches(password,userDetails.getPassword()))
            {
                throw new BadCredentialsException("密码不正确");
            }
            UsernamePasswordAuthenticationToken authenticationToken =
                    new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
            token = jwtTokenUtil.generateToken(userDetails);
        }catch (AuthenticationException e){
            LOGGER.warn("登录异常:{}",e.getMessage());
        }
        return token;
    }

    @Override
    public CommonResult cancelRegister(String username) {
        if(doctorMapper.selectByPrimaryKey(username).getStatus()!=0)
            return CommonResult.success("该注册已经被审核通过不需要延迟删除");
        send_email(username,"超时未审核请重新注册");
        doctorMapper.deleteByPrimaryKey(username);
        return CommonResult.success("成功删除");
    }

    @Override
    public CommonResult registerSendMail(String[] username_validCode) {
        send_email(username_validCode[0],"用户: "+username_validCode[0]+"的验证码为: "+username_validCode[1]);
        return CommonResult.success(username_validCode[0],"成功向该用户"+username_validCode[0]+"发送邮件");
    }

    @Override
    public CommonResult addCase(String Locate, String Note, String Telephone, int Age, String Level, String Disease_type, String gender, HttpServletRequest request) {
        String username = new TranslateToToken().GetUsernameByHeader(request);
        if(username.length()==0)
            return CommonResult.failed("用户名不能为空");
        String uuid = TranslateToToken.GetGUID();
        Case c = new Case();c.setLocate(Locate);c.setTime(new Date());c.setNote(Note);
        c.setTelephone(Telephone);c.setAge(Age);c.setLevel(Level);c.setDiseaseType(Disease_type);
        c.setCaseId(uuid);c.setGender(gender);c.setDoctorTokenId(doctorMapper.selectByPrimaryKey(username).getDoctorTokenId());
        caseMapper.insert(c);
        return CommonResult.success(uuid,"病例成功插入");
    }

    @Override
    public List<Case> getCaseByusername(HttpServletRequest request,int pageNum,int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        String username = new TranslateToToken().GetUsernameByHeader(request);
        if(username.length()==0)
            return new ArrayList<>();
        return   reportSystemDao.getCaseListByDoctorUsername(username);
    }

    @Override
    public CommonResult addAuthCase(CaseDto caseDto) {

        redisTmpService.sAdd(redis_auth_Case_key,(Object) caseDto);
        return CommonResult.success(caseDto.getCaseId(),"成功插入审核redis数据库中");
    }
}
